import React, {
  FC,
  Fragment,
  useCallback,
  useEffect,
  useRef,
  useState,
} from "react";

import {
  Row,
  Col,
  Input,
  Collapse,
  Form,
  Switch,
  Progress,
  Radio,
  Slider,
  Select,
  Button,
} from "antd";
import {
  SearchOutlined,
  StarOutlined,
  PictureOutlined,
  ClusterOutlined,
  PoweroffOutlined,
  SoundOutlined,
  SettingOutlined,
  BugOutlined,
  MessageOutlined,
} from "@ant-design/icons";

import IconFont from "../components/IconFont";

import "./index.less";
import GT2 from "../assets/gt2.png"

const { Panel } = Collapse;

const Main: FC = () => {
  const timerRef = useRef<any>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  const [screenForm] = Form.useForm();
  const [sensorForm] = Form.useForm();
  const [batteryForm] = Form.useForm();
  const [soundForm] = Form.useForm();
  const [deviceSettingForm] = Form.useForm();
  const [debugSettingForm] = Form.useForm();
  const [distributedCapabilityForm] = Form.useForm();

  const [fold, setFold] = useState<boolean>(true);
  const [canvas , setCanvas ] = useState<any>(null);
  const [websocket, setWebsocket] = useState<WebSocket>();
  const [mousePress, setMousePress] = useState<any>(false);
  const [canvasInfo, setCanvasInfo] = useState<any>({
    mouseEvent: "MouseRelease",
    mouseX: 0,
    mouseY: 0,
  });
  const [screenInitValues, setScreenInitValues] = useState<any>({
    screenStatus: true,
    screenMode: true,
    screenDelay: 0,
    brightnessMode: "manual",
    brightness: 60,
  });
  const [sensorInitValues, setSensorInitValues] = useState<any>({
    onbodyStatus: true,
    barometer: 101325,
    heartRate: 63,
    stepCount: 9999,
    longitude: 116.39647,
    latitude: 39.914417,
  });
  const [batteryInitValues, setBatteryInitValues] = useState<any>({
    chargingstatus: "notCharging",
    battery: 99,
  });
  const [soundInitValues, setSoundInitValues] = useState<any>({
    volume: 33,
  });
  const [deviceSettingInitValues, setDeviceSettingInitValues] = useState<any>({
    language: "en-US",
  });
  const [debugSettingInitValues, setDebugSettingInitValues] = useState<any>({
    pointerEventAndLocation: false,
  });
  const [
    distributedCapabilityInitValues,
    setDistributedCapabilityInitValues,
  ] = useState<any>({
    deviceID: "",
    bundleName: "",
    abilityName: "",
    message: "",
  });

  useEffect(() => {
    fetch("/port", {
      method: "GET",
    })
      .then((response) => {
        return response.json();
      })
      .then((json) => {
        setWebsocket(new WebSocket(`ws://localhost:${json}`));
      });

    const canvas = canvasRef.current?.getContext('2d');
    setCanvas(canvas);
  }, []);

  useEffect(() => {
      setScreenInitValues((prevState: any) => ({
        ...prevState,
        screenDelay: 0,
        screenMode: prevState.screenStatus,
      }));
  }, [screenInitValues.screenStatus]);

  useEffect(() => {
    if (screenInitValues.screenMode) {
      setScreenInitValues((prevState: any) => ({
        ...prevState,
        screenDelay: 0,
        screenStatus: true,
      }));
    } else {
      setScreenInitValues((prevState: any) => ({
        ...prevState,
        screenDelay: prevState.screenStatus ? 100 : 0,
      }));
    }
  }, [screenInitValues.screenMode]);

  useEffect(() => {
    if (screenInitValues.screenDelay > 0) {
      timerRef.current = setInterval(() => {
        setScreenInitValues((prevState: any) => ({
          ...prevState,
          screenDelay: screenInitValues.screenDelay - 2,
        }));
      }, 100);
    } else {
      if (timerRef.current < 10) return;

      clearInterval(timerRef.current);
      setScreenInitValues((prevState: any) => ({
        ...prevState,
        screenStatus: prevState.screenMode,
      }));
    }

    return () => {
      clearInterval(timerRef.current);
    };
  }, [screenInitValues.screenDelay]);

  const updateProperties = useCallback(() => {
    const request = {
      version: "1.0.0",
      command: "updateProperties",
      status: "success",
      args: {
        ...screenInitValues,
        ...sensorInitValues,
        ...batteryInitValues,
        ...soundInitValues,
        ...deviceSettingInitValues,
        ...debugSettingInitValues,
      },
    };

    websocket?.send(JSON.stringify(request));
  }, [
    websocket,
    screenInitValues,
    sensorInitValues,
    batteryInitValues,
    soundInitValues,
    deviceSettingInitValues,
    debugSettingInitValues,
  ]);

  const updatCanvas = useCallback((image) => {
    const reader = new FileReader();
    reader.readAsArrayBuffer(image);
    reader.onload = (event) => {
      if (event.target?.readyState === FileReader.DONE) {
        const data = event.target.result as ArrayBufferLike;
        const dataView = new DataView(data);
        
        canvas.clearRect(0, 0, 454, 454);
        const imageData = canvas.createImageData(454, 454);

        for (let i = 0; i < event.total; i += 4) {
          imageData.data[i] = dataView.getUint8(i + 1);
          imageData.data[i + 1] = dataView.getUint8(i + 2);
          imageData.data[i + 2] = dataView.getUint8(i + 3);
          imageData.data[i + 3] = dataView.getUint8(i);
        }

        canvas.putImageData(imageData, 0, 0);
      }
    }
  }, [canvas]);

  useEffect(() => {
    if (websocket) {
      websocket.onerror = () => { };

      websocket.onopen = () => {
        updateProperties();
      };

      websocket.onmessage = (event: any) => {
        if (event.data instanceof Blob) {
          updatCanvas(event.data)
          return
        }

        const response = JSON.parse(event.data);

        console.log(response);
      };

      websocket.onclose = () => { };
    }
  }, [websocket, updateProperties, updatCanvas]);

  const onScreenFormValuesChange = useCallback((values) => {
    setScreenInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onSensorFormValuesChange = useCallback((values) => {
    setSensorInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onBatteryFormValuesChange = useCallback((values) => {
    setBatteryInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onSoundFormValuesChange = useCallback((values) => {
    setSoundInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onDeviceSettingFormValuesChange = useCallback((values) => {
    setDeviceSettingInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onDebugSettingFormValuesChange = useCallback((values) => {
    setDebugSettingInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onDistributedCapabilityFormValuesChange = useCallback((values) => {
    setDistributedCapabilityInitValues((prevState: any) => ({
      ...prevState,
      ...values,
    }));
  }, []);

  const onCanvasMouseMove = useCallback((event) => {
    const mouseX = event.clientX - event.target.offsetLeft;
    const mouseY = event.clientY - event.target.offsetTop;

    setCanvasInfo({
      mouseEvent: mousePress ? "MouseMove" : "MouseRelease",
      mouseX,
      mouseY,
    });
  }, [mousePress]);

  const onCanvasMouseDown = useCallback((event) => {
    setMousePress(true);

    setCanvasInfo((prevState: any) => ({
      ...prevState,
      mouseEvent: "MousePress",
    }));
  }, []);

  const onCanvasMouseUp = useCallback((event) => {
    setMousePress(false);

    setCanvasInfo((prevState: any) => ({
      ...prevState,
      mouseEvent: "MouseRelease",
    }));
  }, []);

  return (
    <Row>
      <Col span={fold ? 24 : 14} className="Render">
        <div className="Simulator">
          <div className={debugSettingInitValues.pointerEventAndLocation ? "PointerTip" : "EmptyPointerTip"}>
            {debugSettingInitValues.pointerEventAndLocation && (
              <Fragment>
                <span>Pointer Event: {canvasInfo.mouseEvent}</span>
                <span>Pointer Location: {canvasInfo.mouseX}:{canvasInfo.mouseY}</span>
              </Fragment>
            )}
          </div>
          <div className="SimulatorBox" style={{ width: 530, height: 626 }}>
            <canvas ref={canvasRef} className="Canvas" width="454" height="454" style={{ borderRadius: debugSettingInitValues.pointerEventAndLocation ? 0 : "50%", zIndex: debugSettingInitValues.pointerEventAndLocation ? 999 : 1, visibility: screenInitValues.screenStatus ? "visible" : "hidden" }}></canvas>
            <div className="SimulatorBG" style={{ width: 530, height: 626, backgroundImage: `url(${GT2})` }} />
            <div className="SimulatorMask" style={{ width: 530, height: 626, backgroundColor: debugSettingInitValues.pointerEventAndLocation ? "#f2f2f2" : "transparent", opacity: debugSettingInitValues.pointerEventAndLocation ? .9 : 1 }} />
            <div className="MouseEvent" style={{ width: 454, height: 454, borderRadius: debugSettingInitValues.pointerEventAndLocation ? 0 : "50%", visibility: screenInitValues.screenStatus ? "visible" : "hidden" }} onMouseMove={onCanvasMouseMove} onMouseDown={onCanvasMouseDown} onMouseUp={onCanvasMouseUp}></div>
          </div>
        </div>
        <div className="Operation">
          <div className="FoldBtn" onClick={() => setFold(!fold)}>
            <IconFont type="icon-menu" style={{ fontSize: 20 }} />
          </div>
        </div>
      </Col>
      <Col span={fold ? 0 : 10} className="Setting">
        <div className="TitleAndSearch">
          <div className="Title">Huawei Lite Wearable 454*454</div>
          {/* <div className="Search">
            <Input
              placeholder="Search"
              suffix={<SearchOutlined style={{ color: "rgba(0,0,0,.45)" }} />}
            />
          </div> */}
        </div>
        <div className="SettingItem">
          <Collapse bordered={false}>
            {/* <Panel
              header={
                <Fragment>
                  <StarOutlined /> Favorites
                </Fragment>
              }
              key="Favorites"
            ></Panel> */}
            <Panel
              header={
                <Fragment>
                  <PictureOutlined /> Screen
                </Fragment>
              }
              key="Screen"
            >
              <Form
                form={screenForm}
                layout="vertical"
                fields={[
                  {
                    name: ["screenStatus"],
                    value: screenInitValues.screenStatus,
                  },
                  { name: ["screenMode"], value: screenInitValues.screenMode },
                  {
                    name: ["screenDelay"],
                    value: screenInitValues.screenDelay,
                  },
                  {
                    name: ["brightnessMode"],
                    value: screenInitValues.brightnessMode,
                  },
                  { name: ["brightness"], value: screenInitValues.brightness },
                ]}
                onValuesChange={onScreenFormValuesChange}
              >
                <Form.Item
                  label="Turn screen on"
                  name="screenStatus"
                  valuePropName="checked"
                >
                  <Switch disabled={debugSettingInitValues.pointerEventAndLocation} />
                </Form.Item>
                <Form.Item label="Keep screen on">
                  <Form.Item
                    className="column"
                    name="screenMode"
                    valuePropName="checked"
                  >
                    <Switch disabled={debugSettingInitValues.pointerEventAndLocation} />
                  </Form.Item>
                  <Form.Item name="screenDelay" valuePropName="percent">
                    <Progress />
                  </Form.Item>
                </Form.Item>
                <Form.Item
                  label="Brightness adjustment mode"
                  name="brightnessMode"
                >
                  <Radio.Group>
                    <Radio value="manual">Manual</Radio>
                    <Radio value="automatic">Automatic</Radio>
                  </Radio.Group>
                </Form.Item>
                <Form.Item label="Brightness">
                  <Form.Item
                    name="brightness"
                    style={{
                      display: "inline-block",
                      width: "calc(80% - 8px)",
                    }}
                  >
                    <Slider
                      min={0}
                      max={100}
                      disabled={screenInitValues.brightnessMode === "automatic"}
                    />
                  </Form.Item>
                  <Form.Item
                    name="brightness"
                    style={{
                      display: "inline-block",
                      width: "calc(20% - 8px)",
                      margin: "0 8px",
                    }}
                  >
                    <Input
                      disabled={screenInitValues.brightnessMode === "automatic"}
                    />
                  </Form.Item>
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <ClusterOutlined /> Sensor
                </Fragment>
              }
              key="Sensor"
            >
              <Form
                form={sensorForm}
                layout="vertical"
                fields={[
                  {
                    name: ["onbodyStatus"],
                    value: sensorInitValues.onbodyStatus,
                  },
                  { name: ["barometer"], value: sensorInitValues.barometer },
                  {
                    name: ["heartRate"],
                    value: sensorInitValues.heartRate,
                  },
                  {
                    name: ["stepCount"],
                    value: sensorInitValues.stepCount,
                  },
                  { name: ["longitude"], value: sensorInitValues.longitude },
                  { name: ["latitude"], value: sensorInitValues.latitude },
                ]}
                onValuesChange={onSensorFormValuesChange}
              >
                <Form.Item
                  label="On-body status"
                  name="onbodyStatus"
                  valuePropName="checked"
                >
                  <Switch />
                </Form.Item>
                <Form.Item label="Barometer(Pa)" name="barometer">
                  <Input />
                </Form.Item>
                <Form.Item label="Heart rate">
                  <Form.Item
                    name="heartRate"
                    style={{
                      display: "inline-block",
                      width: "calc(80% - 8px)",
                    }}
                  >
                    <Slider min={0} max={200} />
                  </Form.Item>
                  <Form.Item
                    name="heartRate"
                    style={{
                      display: "inline-block",
                      width: "calc(20% - 8px)",
                      margin: "0 8px",
                    }}
                  >
                    <Input />
                  </Form.Item>
                </Form.Item>
                <Form.Item label="Step count">
                  <Form.Item
                    name="stepCount"
                    style={{
                      display: "inline-block",
                      width: "calc(80% - 8px)",
                    }}
                  >
                    <Slider min={0} max={99999} />
                  </Form.Item>
                  <Form.Item
                    name="stepCount"
                    style={{
                      display: "inline-block",
                      width: "calc(20% - 8px)",
                      margin: "0 8px",
                    }}
                  >
                    <Input />
                  </Form.Item>
                </Form.Item>
                <Form.Item label="Geographic location">
                  <Form.Item
                    label="Longitude"
                    name="longitude"
                    className="row"
                    style={{
                      display: "inline-block",
                      width: "calc(50% - 80px)",
                      margin: "0 40px",
                    }}
                  >
                    <Input bordered={false} />
                  </Form.Item>
                  <Form.Item
                    label="Latitude"
                    name="latitude"
                    className="row"
                    style={{
                      display: "inline-block",
                      width: "calc(50% - 80px)",
                      margin: "0 40px",
                    }}
                  >
                    <Input bordered={false} />
                  </Form.Item>
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <PoweroffOutlined /> Battery
                </Fragment>
              }
              key="Battery"
            >
              <Form
                form={batteryForm}
                layout="vertical"
                fields={[
                  {
                    name: ["chargingstatus"],
                    value: batteryInitValues.chargingstatus,
                  },
                  { name: ["battery"], value: batteryInitValues.battery },
                ]}
                onValuesChange={onBatteryFormValuesChange}
              >
                <Form.Item label="Charging status" name="chargingstatus">
                  <Radio.Group>
                    <Radio value="notCharging">Not charging</Radio>
                    <Radio value="charging">Charging</Radio>
                    <Radio value="wirelessCharging">Wireless Charging</Radio>
                  </Radio.Group>
                </Form.Item>
                <Form.Item label="Battery level">
                  <Form.Item
                    name="battery"
                    style={{
                      display: "inline-block",
                      width: "calc(80% - 8px)",
                    }}
                  >
                    <Slider
                      min={0}
                      max={100}
                      disabled={
                        batteryInitValues.chargingstatus !== "notCharging"
                      }
                    />
                  </Form.Item>
                  <Form.Item
                    name="battery"
                    style={{
                      display: "inline-block",
                      width: "calc(20% - 8px)",
                      margin: "0 8px",
                    }}
                  >
                    <Input
                      disabled={
                        batteryInitValues.chargingstatus !== "notCharging"
                      }
                    />
                  </Form.Item>
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <SoundOutlined /> Sound
                </Fragment>
              }
              key="Sound"
            >
              <Form
                form={soundForm}
                layout="vertical"
                fields={[
                  {
                    name: ["volume"],
                    value: soundInitValues.volume,
                  },
                ]}
                onValuesChange={onSoundFormValuesChange}
              >
                <Form.Item label="Volume">
                  <Form.Item
                    name="volume"
                    style={{
                      display: "inline-block",
                      width: "calc(80% - 8px)",
                    }}
                  >
                    <Slider min={0} max={100} />
                  </Form.Item>
                  <Form.Item
                    name="volume"
                    style={{
                      display: "inline-block",
                      width: "calc(20% - 8px)",
                      margin: "0 8px",
                    }}
                  >
                    <Input />
                  </Form.Item>
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <SettingOutlined /> Device Settings
                </Fragment>
              }
              key="DeviceSetting"
            >
              <Form
                form={deviceSettingForm}
                layout="vertical"
                fields={[
                  {
                    name: ["language"],
                    value: deviceSettingInitValues.language,
                  },
                ]}
                onValuesChange={onDeviceSettingFormValuesChange}
              >
                <Form.Item label="Language" name="language">
                  <Select>
                    <Select.Option value="zh-CN">zh-CN</Select.Option>
                    <Select.Option value="en-US">en-US</Select.Option>
                  </Select>
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <BugOutlined /> Debugging
                </Fragment>
              }
              key="Debugging"
            >
              <Form
                form={debugSettingForm}
                layout="vertical"
                fields={[
                  {
                    name: ["pointerEventAndLocation"],
                    value: debugSettingInitValues.pointerEventAndLocation,
                  },
                ]}
                onValuesChange={onDebugSettingFormValuesChange}
              >
                <Form.Item
                  label="Pointer event and location"
                  valuePropName="checked"
                  name="pointerEventAndLocation"
                >
                  <Switch disabled={!screenInitValues.screenStatus} />
                </Form.Item>
              </Form>
            </Panel>
            <Panel
              header={
                <Fragment>
                  <MessageOutlined /> Distributed Capability
                </Fragment>
              }
              key="DistributedCapability"
            >
              <Form
                form={distributedCapabilityForm}
                layout="vertical"
                fields={[
                  {
                    name: ["deviceID"],
                    value: distributedCapabilityInitValues.deviceID,
                  },
                  {
                    name: ["bundleName"],
                    value: distributedCapabilityInitValues.bundleName,
                  },
                  {
                    name: ["abilityName"],
                    value: distributedCapabilityInitValues.abilityName,
                  },
                  {
                    name: ["message"],
                    value: distributedCapabilityInitValues.message,
                  },
                ]}
                onValuesChange={onDistributedCapabilityFormValuesChange}
              >
                <Form.Item label="Distributed communications">
                  <Form.Item
                    className="column"
                    label="Device ID"
                    name="deviceID"
                  >
                    <Input bordered={false} placeholder="Device ID" />
                  </Form.Item>
                  <Form.Item
                    className="column"
                    label="Bundle name"
                    name="bundleName"
                  >
                    <Input bordered={false} placeholder="Bundle name" />
                  </Form.Item>
                  <Form.Item
                    className="column"
                    label="Ability name"
                    name="abilityName"
                  >
                    <Input bordered={false} placeholder="Ability name" />
                  </Form.Item>
                  <Form.Item className="column" label="Message" name="message">
                    <Input.TextArea placeholder="Message" />
                  </Form.Item>
                </Form.Item>
                <Form.Item className="submit">
                  <Button type="primary" style={{ width: 100 }}>
                    Send
                  </Button>
                </Form.Item>
              </Form>
            </Panel>
          </Collapse>
        </div>
      </Col>
    </Row>
  );
};

export default Main;
